package server.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import plug.result.ReqPage;
import plug.result.RetResponse;
import plug.result.RetResult;

import server.dao.*;
import server.model.dto.UserDto;
import server.model.dto.UsersAdDto;
import server.model.entity.BlanceRecord;
import server.model.entity.UserBlance;
import server.model.entity.Users;
import server.model.vo.BlanceRecordVo;
import server.service.UserBlanceService;
import server.service.UserService;
import server.tool.tool.BeanUtil;
import server.tool.tool.EDcrypionUtils;
import server.tool.tool.TimeUtils;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 创建人:    xvzhe
 * 创建时间:
 * 修改时间:
 * 版本:      v1.0
 */
@RestController
@RequestMapping("v1/api/user")
@CrossOrigin(origins = "*")
public class UserAdController {
    @Autowired
    UsersDao usersDao;
    @Autowired
    UserService userService;
    @Autowired
    UserBlanceDao userBlanceDao;
    @Autowired
    UserSiteDao userSiteDao;
    @Autowired
    UserDepositDao userDepositDao;
    @Autowired
    BlanceRecordDao blanceRecordDao;
    @Autowired
    UserBlanceService userBlanceService;

    @PostMapping("/all")
    public RetResult all(@RequestBody ReqPage reqPage) {
        JSONObject req = Optional.ofNullable(reqPage.getCommon()).orElseGet(JSONObject::new);
        Users entity = JSON.parseObject(req.toJSONString(), Users.class);
        int page = reqPage.getPage() - 1;
        int size = reqPage.getLimit();
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "createTime");
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<Users> example = Example.of(entity, matcher);
        Page<Users> pages = usersDao.findAll(example, pageable);
        List<Users> pageList = pages.getContent();
        List<UsersAdDto> ad = pageList.stream().map(item -> BeanUtil.convertToBean(item, UsersAdDto.class)).collect(Collectors.toList());
        ad.forEach(item -> {
            item.setUserBlances(userBlanceDao.findByUserId(item.getId()));
        });
        return RetResponse.makeRsp(0, "成功", ad, (int) pages.getTotalElements());
    }

    @PostMapping("/blance/all")
    public RetResult blanceAll(@RequestBody ReqPage reqPage) {
        JSONObject req = Optional.ofNullable(reqPage.getCommon()).orElseGet(JSONObject::new);
        Users entity = JSON.parseObject(req.toJSONString(), Users.class);
        BlanceRecord blanceRecord = JSON.parseObject(req.toJSONString(), BlanceRecord.class);
        blanceRecord.setStatus(true);
        if (StringUtils.isNotBlank(entity.getName())) {
            List<Users> s = usersDao.findByNameLike(entity.getName());
            if (Optional.ofNullable(s).isPresent()) {
                blanceRecord.setUserId(s.get(0).getId());
            }
        }
        int page = reqPage.getPage() - 1;
        int size = reqPage.getLimit();
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "modifiedTime");
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("log", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<BlanceRecord> example = Example.of(blanceRecord, matcher);
        Page<BlanceRecord> pages = blanceRecordDao.findAll(example, pageable);
        List<BlanceRecord> pageList = pages.getContent();
        List<BlanceRecordVo> userVo = new LinkedList<>();
        pageList.forEach(item -> {
            BlanceRecordVo us = BeanUtil.convertToBean(item, BlanceRecordVo.class);
            us.setUsers(usersDao.findById(us.getUserId()).get());
            userVo.add(us);
        });
        return RetResponse.makeRsp(0, "成功", userVo, (int) pages.getTotalElements());
    }

    @PutMapping("/blance/{userId}")
    @ApiOperation("钱包修改")
    public RetResult putBlance(@PathVariable String userId, UserBlance.Type type, BigDecimal money) {
        if (userService.checkStatus(userId)) {
            if (money.compareTo(BigDecimal.ZERO) > 0) {
                userBlanceService.insBlance(userId, money, type, BlanceRecord.Type.AD_INS);
            } else {
                userBlanceService.insBlance(userId, money, type, BlanceRecord.Type.AD_DEL);
            }
            return RetResponse.makeOKRsp();
        } else {
            return RetResponse.makeErrRsp("账号未激活");
        }
    }

    @GetMapping("/password/reload/{userId}")
    public RetResult psdReload(@PathVariable String userId) {
        Users us = usersDao.findById(userId).get();
        us.setPassword(EDcrypionUtils.shiroPassword("123456"));
        usersDao.save(us);
        return RetResponse.makeOKRsp();
    }

    @GetMapping("/status/reload/{userId}")
    public RetResult statusReload(@PathVariable String userId) {
        Users us = usersDao.findById(userId).get();
        if (us.getStatus()) {
            us.setStatus(false);
        } else {
            us.setStatus(true);
        }
        usersDao.save(us);
        return RetResponse.makeOKRsp();
    }

    @GetMapping("/blance/{userId}")
    public RetResult getBlance(@PathVariable String userId) {
        return RetResponse.makeOKRsp(userBlanceDao.findByUserId(userId));
    }

    @ApiOperation("我的钱包")
    @GetMapping("/blance")
    public RetResult getBlance() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        return RetResponse.makeOKRsp(userBlanceDao.findByUserId(users.getId()));
    }

    @GetMapping("/site/{userId}")
    public RetResult getSite(@PathVariable String userId) {
        return RetResponse.makeOKRsp(userSiteDao.findByUserIdAndStatus(userId, true));
    }

    @GetMapping("/deposit/{userId}")
    public RetResult getDeposit(@PathVariable String userId) {
        return RetResponse.makeOKRsp(userDepositDao.findByUserIdAndStatus(userId, true));
    }

    @DeleteMapping("/{userId}")
    @Transactional
    public RetResult delUser(@PathVariable String userId) {
        try {
            Optional<Users> uf = usersDao.findById(userId);
            Optional<Users> up = usersDao.findById(uf.get().getParentId());
            up.get().setInviteNum(up.get().getInviteNum() - 1);
            usersDao.save(up.get());
            usersDao.deleteById(userId);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RetResponse.makeErrRsp("当前用户不允许删除");
        }
        return RetResponse.makeOKRsp();
    }

    @GetMapping("/userInfo/{userId}")
    public RetResult getUser(@PathVariable String userId) {
        return RetResponse.makeOKRsp(usersDao.findById(userId));
    }

    @PutMapping("/userInfo/{userId}")
    public RetResult putsUser(@PathVariable String userId, @RequestBody UserDto userDto) {
        Users us = usersDao.findById(userId).get();
        us.setGrade(userDto.getGrade());
        us.setUserName(userDto.getUserName());
        us.setPassword(EDcrypionUtils.shiroPassword(userDto.getPassword()));
        us.setMobile(userDto.getMobile());
        try {
            usersDao.save(us);
        } catch (Exception e) {
            return RetResponse.makeErrRsp("失败");
        }
        return RetResponse.makeOKRsp();
    }

    @PutMapping("/userActive/{userId}")
    public RetResult userActive(@PathVariable String userId) {
        Users us = usersDao.findById(userId).get();
        if(us.getActive()){
            us.setActive(false);
        }else{
            us.setActive(true);
        }
        try {
            usersDao.save(us);
        } catch (Exception e) {
            return RetResponse.makeErrRsp("失败");
        }
        return RetResponse.makeOKRsp();
    }

    @PutMapping("/userPermance/{userId}")
    public RetResult userPermance(@PathVariable String userId, Integer permance) {
        Users us = usersDao.findById(userId).get();
        us.setPerformance(permance);
        try {
            usersDao.save(us);
        } catch (Exception e) {
            return RetResponse.makeErrRsp("失败");
        }
        return RetResponse.makeOKRsp();
    }

    @GetMapping("/performance/{userId}")
    @ApiOperation("团队业绩")
    public RetResult performance(@PathVariable String userId) {
        Map<String, Object> re = Maps.newHashMap();
        Map<String, Integer> mp = Maps.newHashMap();
        usersDao.findByParentId(userId).stream().forEach(item -> {
            mp.put(item.getName(), item.getPerformance());
        });
        re.put("total",mp.values().stream().mapToInt(item->item).sum());
        re.put("list",mp);
        return RetResponse.makeOKRsp(re);
    }
}
